package com.intelligent.ispc.foundation.poi;

import com.intelligent.ispc.foundation.pdf.TableStyleConfig;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Eligi.Ran on 2016/9/5.
 */
public class ExcelTemplateImpl implements ExcelTemplate {
    private XSSFWorkbook workbook;


    public ExcelTemplateImpl() {
        workbook = new XSSFWorkbook();
    }

    public Workbook getWorkbook() {
        return workbook;
    }

    @Override
    public void appendTableAndChart(Sheet sheet, List<String> metadatas, Object[][] values, TableStyleConfig styleConfig, String imagePath, Map<Integer, String> mark) {
        XSSFSheet tableSheet = PoiComponentFactory.paintTable(metadatas, values, styleConfig, mark);
        int rowInterval = 20;
        int[] positionParams = copyTableToSheet(tableSheet, sheet);
        int lastRow = positionParams[0];
        int colCounter = positionParams[1];
        int metaDataLength = metadatas.size();
        if (rowInterval < metaDataLength) {
            rowInterval = metaDataLength;
        }
        if (imagePath != null) {
            Integer image = PoiComponentFactory.paintImage(workbook, imagePath);
            combineChart(sheet, image, lastRow, colCounter + 1);
        } else {
            rowInterval = metaDataLength;
        }
        sheet.createRow(lastRow + rowInterval).createCell(0).setCellValue(" ");
        for (int i = 0; i < colCounter; i++) {
            sheet.autoSizeColumn(i);
        }

    }


    @Override
    public void appendTableSheet(Sheet sheet, List<String> metadatas, Object[][] values) {
        TableStyleConfig styleConfig = new TableStyleConfig(TableStyleConfig.HORIZONTAL);
        XSSFSheet sourceSheet = PoiComponentFactory.paintTable(metadatas, values, styleConfig, null);
        copyTableToSheet(sourceSheet, sheet);
        int colNum = sheet.getPhysicalNumberOfRows();
        for (int i = 0; i < colNum; i++) {
            sheet.autoSizeColumn(i);
            if (sheet.getColumnWidth(i) < 2048) {
                sheet.setColumnWidth(i, 2048);
            }
        }
    }

    public void exportExcel(String savePath) {
        File xlsxFile = createFile(savePath);
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream(xlsxFile);
            workbook.write(fileOut);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileOut != null) {
                    fileOut.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void combineChart(Sheet sheet, int image, int startRow, int startCol) {
        Drawing drawing = sheet.createDrawingPatriarch();

        CreationHelper helper = workbook.getCreationHelper();
        //add a picture shape
        ClientAnchor anchor = helper.createClientAnchor();
        //set top-left corner of the picture,
        //subsequent call of Picture#resize() will operate relative to it
        anchor.setCol1(startCol);
        anchor.setRow1(startRow);
        anchor.setRow2(startRow + 20);
        anchor.setCol2(startCol + 12);
        Picture pict = drawing.createPicture(anchor, image);
        pict.resize(1, 1);
    }

    private int[] copyTableToSheet(XSSFSheet tableSheet, Sheet targetSheet) {
        List<XSSFTable> tableTest = tableSheet.getTables();
        XSSFTable table = tableTest.get(0);
        int startRow = table.getStartCellReference().getRow();
        int endRow = table.getEndCellReference().getRow();
        int startColumn = table.getStartCellReference().getCol();
        int endColumn = table.getEndCellReference().getCol();
        int lastRow = targetSheet.getLastRowNum() + 1;
        Row row;
        Row gotRow;
        int rowCounter = 0, colCounter = 0;
        if (lastRow == 1) {
            lastRow = 0;
        }
        CellStyle cellStyle, tableCellStyle;
        Font font, tableFont;
        for (int i = startRow; i <= endRow; i++) {
            row = targetSheet.createRow(lastRow + rowCounter);
            gotRow = tableSheet.getRow(i);
            Cell cell, tableCell;
            String value;
            colCounter = 0;
            for (int j = startColumn; j <= endColumn; j++) {
                cell = row.createCell(colCounter++);
                tableCell = gotRow.getCell(j);
                cellStyle = workbook.createCellStyle();
                tableCellStyle = tableCell.getCellStyle();
                cellStyle.cloneStyleFrom(tableCellStyle);
                cell.setCellStyle(cellStyle);
                value = tableCell.getStringCellValue();
                if (value.length() > 20 && colCounter == 2) {
                    int currentRow = lastRow + rowCounter;
                    int currentCol = colCounter - 1;
                    targetSheet.addMergedRegion(new CellRangeAddress(currentRow, currentRow, currentCol, currentCol + 12));
                }
                cell.setCellValue(tableCell.getStringCellValue());
            }
            rowCounter++;

        }
        return new int[]{lastRow, colCounter};
    }

    public static void main(String[] args) {
        ExcelTemplateImpl excelTemplate = new ExcelTemplateImpl();
//        excelTemplate.init();
        Workbook wb = excelTemplate.workbook;
        List<String> paramMetadatas = new ArrayList<>();
        paramMetadatas.add("TestParam 1");
        paramMetadatas.add("TestParam 2");
        Object[][] paramObjects = new Object[1][2];
        paramObjects[0][0] = " Param 1";
        paramObjects[0][1] = " Param 2";

        String imagePath = "E:/images.png";
//        int image = PoiComponentFactory.paintImage(wb, "E:/images.png");

        Sheet sheet = wb.createSheet("testPage");
        Sheet dataSheet = wb.createSheet("dataPage");
        TableStyleConfig tableStyleConfig = new TableStyleConfig(1);
        excelTemplate.appendTableAndChart(sheet, paramMetadatas, paramObjects, tableStyleConfig, null, null);
        excelTemplate.appendTableAndChart(sheet, paramMetadatas, paramObjects, tableStyleConfig, imagePath, null);
        excelTemplate.appendTableAndChart(sheet, paramMetadatas, paramObjects, tableStyleConfig, imagePath, null);
        excelTemplate.appendTableSheet(dataSheet, paramMetadatas, paramObjects);
        excelTemplate.exportExcel("E:/test2.xls");

    }

    private static File createFile(String pdfPath) {
        File pdfFile = new File(pdfPath);
        if (pdfFile.exists()) {
            pdfFile.delete();
        }
        try {
            pdfFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return pdfFile;
    }

}
